#include "t_box_seq.h"

T_Box_Sequence_Proxy *T_Box_Sequence::open()
{
    return new T_Box_Sequence_Proxy(this);
}

QString T_Box_Sequence::displayName()
{
    if(m_name.isEmpty()) return this->displayNameDefault();
    return m_name;
}

void T_Box_Sequence::displayName(const QString &a_name)
{
    m_name = a_name;
}

T_Box_Sequence_Proxy::T_Box_Sequence_Proxy(T_Box_Sequence *a_seq)
    : m_seq(a_seq)
    , m_pos(0)
{
}

bool T_Box_Sequence_Proxy::isValid()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_seq->isValid();
}
qint64 T_Box_Sequence_Proxy::expectedSize()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_seq->expectedSize();
}
qint64 T_Box_Sequence_Proxy::pos()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_pos;
}

bool T_Box_Sequence_Proxy::isFinished()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_seq->isFinished();
}

qint64 T_Box_Sequence_Proxy::availableSize()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_seq->availableSize();
}
void T_Box_Sequence_Proxy::p_wait_one_step()
{
    if(qApp->thread() == QThread::currentThread())
    {
        qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
    }
    T_Sleeper::msleep(1);
}

bool T_Box_Sequence_Proxy::seek(qint64 a_offset)
{
    /*
    T_ATOMIC_LOCKER(v_lock, m_seq)
    if(m_seq->seek(a_offset))
    {
        m_pos = m_seq->pos();
        return true;
    }
    return false;
    */
    if(a_offset<0) return false;
    while(!this->isFinished() && a_offset>this->availableSize())
    {
        p_wait_one_step();
    }
    if(a_offset<=this->availableSize())
    {
        m_pos = a_offset;
        return true;
    }
    return false;
}

QByteArray T_Box_Sequence_Proxy::wait_read(qint64 a_max_size)
{
    /*
    T_ATOMIC_LOCKER(v_lock, m_seq)
    if(!m_seq->seek(m_pos))
    {
        return QByteArray();
    }
    QByteArray v_bytes = m_seq->wait_read(a_max_size);
    m_pos = m_seq->pos();
    return v_bytes;
    */
    if(a_max_size<=0) return QByteArray();
    while(!this->isFinished() && (m_pos+a_max_size)>this->availableSize())
    {
        p_wait_one_step();
    }
    {
        T_ATOMIC_LOCKER(v_lock, m_seq)
        if(!m_seq->seek(m_pos))
        {
            Q_ASSERT(0);
            return QByteArray();
        }
        QByteArray v_bytes = m_seq->wait_read(a_max_size);
        m_pos = m_seq->pos();
        return v_bytes;
    }
}

int T_Box_Sequence_Proxy::bufferSize()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_seq->bufferSize();
}

QString T_Box_Sequence_Proxy::displayName()
{
    T_ATOMIC_LOCKER(v_lock, m_seq)
    return m_seq->displayName();
}
